package org.zhouhe.base;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.zhouhe.page.PageUtil;
import org.zhouhe.vo.User;

@Repository
@SuppressWarnings({"unchecked","rawtypes"})
public class BaseDao extends HibernateDaoSupport {
	@Autowired
	public void autoSetSuperSessionFactory(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}

	// basic operation:
	public void save(Object entity) {
		this.getHibernateTemplate().save(entity);
	}

	public void update(Object entity) {
		this.getHibernateTemplate().update(entity);
	}

	public int executeUpdate(final String hql) {
		return executeUpdate(hql, null);
	}
	public int executeUpdate(final String hql, final List<Object> param) {
		return this.getHibernateTemplate().execute(new HibernateCallback<Integer>() {
			public Integer doInHibernate(Session sess) throws HibernateException, SQLException {
				Query q = sess.createQuery(hql);
				if (param != null && param.size() > 0) {
					for (int i = 0; i < param.size(); i++) {
						q.setParameter(i, param.get(i));
					}
				}
				return q.executeUpdate();
			}
		});
	}

	public void saveOrUpdate(Object entity) {
		this.getHibernateTemplate().saveOrUpdate(entity);
	}

	public void delete(Object entity) {
		this.getHibernateTemplate().delete(entity);
	}

	public void deleteAll(Collection entities) {
		this.getHibernateTemplate().deleteAll(entities);
	}

	public Object get(Class entityClass, Serializable id) {
		return this.getHibernateTemplate().get(entityClass, id);
	}

	public List find(String hql) {
		return this.getHibernateTemplate().find(hql);
	}

	public List<Object> find(String hql, Object... values) {
		return this.getHibernateTemplate().find(hql, values);
	}

	/**
	 * 分布查询，可根据SQL或HQL查询数据。</br > <b>使用SQL查询：</b></br > PageUtil pageUtil = new PageUtil();</br > String select =
	 * "select * ";</br > String from = "from user where login_name = ? and real_name like ? order by user_id desc"
	 * ;</br > List paramList = new ArrayList();</br > paramList.add("zhouhe");</br > paramList.add("%周鹤%");</br >
	 * pageUtil.setSQL(select, from, paramList);</br > <b>使用HQL查询：</b></br > 与使用SQL查询的区别只是select和from中的查询语法改成HQL语法。
	 * 
	 * @param pageUtil
	 * @return PageUtil
	 */
	public PageUtil findByPage(final PageUtil pageUtil) {
		this.getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				if (pageUtil.sql != null) {// 使用SQL查询：
					List<Object> paramList = pageUtil.sql.getParamList();
					if (pageUtil.getTotalRecordCount() == 0) {
						SQLQuery q = session.createSQLQuery(pageUtil.sql.getSql4Count());
						if (paramList != null && paramList.size() > 0) {
							for (int i = 0; i < paramList.size(); i++) {
								q.setParameter(i, paramList.get(i));
							}
						}
						Object totalRecord = q.uniqueResult();
						pageUtil.setTotalRecordCount(new Integer(totalRecord.toString()));
					}
					// pageData:
					System.out.println("getSql4Data>>>>>"+ pageUtil.sql.getSql4Data());
					SQLQuery queryData = session.createSQLQuery(pageUtil.sql.getSql4Data());
					if (paramList != null && paramList.size() > 0) {
						for (int i = 0; i < paramList.size(); i++) {
							queryData.setParameter(i, paramList.get(i));
						}
					}
					queryData.setFirstResult(pageUtil.getPageSize() * (pageUtil.getShowPage() - 1));
					queryData.setMaxResults(pageUtil.getPageSize());
					queryData.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
					pageUtil.setPageData(queryData.list());
					
				} else if (pageUtil.hql != null) {// 使用HQL查询：
					List<Object> paramList = pageUtil.hql.getParamList();
					if (pageUtil.getTotalRecordCount() == 0) {
						Query q = session.createQuery(pageUtil.hql.getHql4Count());
						if (paramList != null && paramList.size() > 0) {
							for (int i = 0; i < paramList.size(); i++) {
								q.setParameter(i, paramList.get(i));
							}
						}
						Object totalRecord = q.uniqueResult();
						String qstr = q.getQueryString();
						System.out.println("qstr" + qstr);
						System.out.println("totalRecord=" + totalRecord);
						pageUtil.setTotalRecordCount(new Integer(totalRecord.toString()));
					}
					// pageData:
					Query q = session.createQuery(pageUtil.hql.getHql4Data());
					if (paramList != null && paramList.size() > 0) {
						for (int i = 0; i < paramList.size(); i++) {
							q.setParameter(i, paramList.get(i));
						}
					}
					q.setFirstResult(pageUtil.getPageSize() * (pageUtil.getShowPage() - 1));
					q.setMaxResults(pageUtil.getPageSize());
					pageUtil.setPageData(q.list());
				}
				return null;
			}
		});
		return pageUtil;
	}

	public void test() {
		this.getHibernateTemplate().execute(new HibernateCallback() {

			public Object doInHibernate(Session sess) throws HibernateException, SQLException {
				for (int i = 0; i < 5000; i++) {
					User u = new User();
					u.setLoginName("beyondcool");
					u.setLoginPwd("12345678");
					u.setRealName("北京开拓天际科技有限公司");
					sess.save(u);
				}
				return null;
			}

		});
	}
}
